<?php

namespace App\Services\Oss;

use App\Common\Traits\LogTrait;
use OSS\Core\OssException;
use OSS\Credentials\StaticCredentialsProvider;
use OSS\Http\RequestCore_Exception;
use OSS\OssClient;

class OssService
{
    use LogTrait;

    //
    public function directUploadPolicy($relativePath,$fileName):array{
        $key=$relativePath.'/'.$fileName;
        $host='https://'.$this->getBucket() . '.' . $this->getDomain();
        $policyArray=$this->getPolicy($key);
        $policyBase64 = base64_encode(json_encode($policyArray));
        $signature = $this->getPolicySignature($policyBase64);
        return [
            'access_key_id' => $this->getAccessKeyId(),
            'host' =>$host,
            'name'=>$fileName,
            'key' => $key,
            'policy' => $policyBase64,
            'signature' => $signature,
            'oss_file_url' => $host. '/' .$key,
        ];
    }
    //
    public function getPolicy($key):array{
        $expiration = gmdate('Y-m-d\TH:i:s\Z', time()+3600); // 设置过期时间为UTC时间
        $conditions=$this->policyConditions($key);
        return [
            'expiration' => $expiration, // 过期时间
            'conditions' => $conditions  // 条件
        ];
    }
    //
    public function policyConditions($key):array{
        return  [
            ['bucket'=>$this->getBucket()], // 指定上传到的Bucket
            ['eq', '$key', $key], // 指定上传到的Object的Key
            ['content-length-range', 1, 20971520],    //20*1024*1024
        ];
    }
    //
    public function getPolicySignature($policyBase64):string{
        return base64_encode(hash_hmac('sha1', $policyBase64, $this->getAccessKeySecret(), true));
    }

    //
    public function storeOssFile($localFileName,$ossFileName):mixed{
        $provider = $this->getProvider();
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        $endpoint = $this->getEndpoint();
        // 填写Bucket名称，例如examplebucket。
        $bucket= $this->getBucket();
        // 填写Object完整路径，例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
        $object = $ossFileName;
        // 填写本地文件的完整路径，例如D:\\localpath\\examplefile.txt。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件。
        $filePath = $localFileName;
        try{
            $config = array(
                "provider" => $provider,
                "endpoint" => $endpoint,
            );
            $ossClient = new OssClient($config);
            $res=$ossClient->uploadFile($bucket, $object, $filePath);
            if(isset($res['info']) && isset($res['info']['url'])){
                return $res['info']['url'];
            }
            return '';
        } catch(OssException|RequestCore_Exception $e) {
            $this->saveExceptionLog('upload oss file failed',$e,$localFileName,$ossFileName);
            return '';
        }
    }
    //
    public function deleteOssFile($ossFileName): ?array
    {
        $provider = $this->getProvider();
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        $endpoint = $this->getEndpoint();
        // 填写Bucket名称，例如examplebucket。
        $bucket= $this->getBucket();
        // 填写Object完整路径，例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。
        $object = $ossFileName;
        try{
            $config = array(
                "provider" => $provider,
                "endpoint" => $endpoint,
            );
            $ossClient = new OssClient($config);
            return $ossClient->deleteObject($bucket, $object);
        } catch(OssException|RequestCore_Exception $e) {
            $this->saveExceptionLog('delete oss file failed',$e,$ossFileName);
            return null;
        }
    }

    //
    public function getProvider(): StaticCredentialsProvider{
        // 从环境变量中获取RAM用户的访问密钥（AccessKey ID和AccessKey Secret）。
        $accessKeyId = $this->getAccessKeyId();
        $accessKeySecret = $this->getAccessKeySecret();
        // 使用代码嵌入的RAM用户的访问密钥配置访问凭证。
        return new StaticCredentialsProvider($accessKeyId, $accessKeySecret);
    }
    //
    public function getAccessKeyId(){
        return config('strator.oss_telesale.access_key_id');
    }
    //
    public function getAccessKeySecret(){
        return config('strator.oss_telesale.access_key_secret');
    }
    //
    public function getEndpoint(){
        return config('strator.oss_telesale.endpoint');
    }
    //
    public function getEndpointInternal(){
        return config('strator.oss_telesale.endpoint_internal');
    }
    //
    public function getBucket(){
        return config('strator.oss_telesale.bucket');
    }
    //
    public function getDomain(){
        return config('strator.oss_telesale.private_domain')?:$this->getEndpoint();
    }

}
